package com.xiaotu.spider.baidu.pageprocessor;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.NetTVModel;
import com.xiaotu.common.model.TVRoleModel;
import com.xiaotu.common.util.*;
import com.xiaotu.spider.APageProcessor;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @类名 TVBaiduBaikeRolePageProcessor
 * @日期 2017年2月15日
 * @作者 高海军
 * @功能 爬取电视剧百度百科数据，主要是角色介绍
 */
@Component("TVBaiduBaikeRolePageProcessor")
public class TVBaiduBaikeRolePageProcessor extends APageProcessor
{

    private static final String SEARCH_URL = "https://baike.baidu.com/item/%s";

    private static final String REMOVE_REG_ROLE = "(\\[" + RegexUtils.REGEX_INTEGER + "\\])|\\s";

    private static final String REPLACE_REG = ",|，|;|；|/|／|、";

    private static final String REMOVE_REG = REMOVE_REG_ROLE + "|(（.+）)|(\\(.+\\))";


    private String filePath;

    @Override
    public void initRunParams(Map<String, Object> map)
    {
        if (map.get("filePath") == null)
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);
        this.filePath = map.get("filePath").toString();
    }

    @Override
    public void process(Page page)
    {
        List<String> liList = page.getHtml().xpath("//li[@class='roleIntroduction-item']").all();
        if (liList == null || liList.isEmpty())
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);
        List<TVRoleModel> roleList = new ArrayList<>(liList.size());
        String tvId = page.getRequest().getExtra("tvid").toString();
        String tvName = page.getRequest().getExtra("tvName").toString();
        liList.forEach(liStr ->
        {
            Html liObj = new Html(liStr);
            roleList.add(new TVRoleModel(tvId, tvName, this.getFormatedData(HtmlUtil.delHTMLTag
                    (liObj.xpath("//div[@class='role-name']").get())), this.getFormatedData
                    (HtmlUtil.delHTMLTag(liObj.xpath
                            ("//div[@class='role-actor']/span[@class='item-value']").get())),
                    RegexUtils.replaceStr(StringUtils.trim(HtmlUtil.delHTMLTag(liObj.xpath
                                    ("//dd[@class='role-description']").get())), REMOVE_REG_ROLE,
                            StringUtils.EMPTY)));
        });
        page.putField(TVRoleModel.class.getName(), roleList);

        List<String> nameList = page.getHtml().xpath("//dt[@class='basicInfo-item name']").all();
        List<String> valueList = page.getHtml().xpath("//dd[@class='basicInfo-item value']").all();

        String director = null, actor = null, type = null;
        if (nameList != null && !nameList.isEmpty() && nameList != null && nameList.size() ==
                valueList.size())
        {
            Map<String, String> map = IntStream.range(0, nameList.size()).mapToObj(i -> i)
                    .collect(Collectors.toMap(i -> StringUtils.trim(HtmlUtil.delHTMLTag(nameList
                            .get(i))), i -> StringUtils.trim(HtmlUtil.delHTMLTag(valueList.get(i)
                    ))));
            director = this.getFormatedData(map.get("导演"));
            actor = this.getFormatedData(map.get("主演"));
            type = this.getFormatedData(map.get("类型"));
        }
        NetTVModel tv = new NetTVModel(tvId, tvName, null, null, type, null, null, null,
                director, actor, null, null, null, null);
        tv.setUrl(page.getUrl().toString());
        page.putField(NetTVModel.class.getName(), tv);
        page.putField("filePath", filePath);
    }

    private String getFormatedData(String data)
    {
        return RegexUtils.replaceStr(RegexUtils.replaceStr(data, REPLACE_REG, SepratorUtil
                .SEP_COMMA_EN), REMOVE_REG, StringUtils.EMPTY);
    }

    @Override
    protected Request getStartRequest(JSONObject target)
    {
        return new Request(String.format(SEARCH_URL, KeywordEncode.encode(target.getString
                ("tvName"))));
    }

    @Override
    public String getPageDataType(Page page)
    {
        return Constants.PageDataType.TV_RECORD;
    }

    @Override
    protected String getSpiderType()
    {
        return "TV_BAIKE";
    }
}
